package com.netty.pro.netty.nio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * @author xuzn
 * @ClassName: ScatteringAndGatheringBuffer
 * @ProjectName echo-project
 * @date 2020/3/5/16:23
 */
public class ScatteringAndGatheringBuffer {
  /**
   * scattering:将数据写到buffer时,可以采用buffer数组,依次写入(分散)
   * gathering:将buffer读取数据时,可以采用buffer数组,依次读
   */
  public static void main(String[] args) throws Exception {
    // 使用ServerSocket
    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    InetSocketAddress inetSocketAddress = new InetSocketAddress(7000);
    // 绑定端口号
    serverSocketChannel.socket().bind(inetSocketAddress);
    // 创建buffer数组
    ByteBuffer[] byteBuffers = new ByteBuffer[2];
    byteBuffers[0] = ByteBuffer.allocate(5);
    byteBuffers[1] = ByteBuffer.allocate(3);
    // 等待客户端链接
    SocketChannel socketChannel = serverSocketChannel.accept();
    int messageLength = 8;
    for (; ; ) {
      long byteread = 0;
      while (byteread < messageLength) {
        long l = socketChannel.read(byteBuffers);
        // 累计读取字节数
        byteread += l;
        // 使用流打印,查看当前的position和limit
        System.out.println("byteread=" + byteread);
        Arrays.asList(byteBuffers).stream().map(buffer -> "position=" + buffer.position() + ",limit=" + buffer.limit())
                .forEach(System.out::println);
      }
      // 将所有的buffer进行flip
      Arrays.asList(byteBuffers).stream().forEach(buffer -> buffer.flip());
      // 将数据读出显示到客户端
      long byteWrite = 0;
      while (byteWrite < messageLength) {
        long l = socketChannel.write(byteBuffers);
        byteWrite += l;
      }
      // 将所有的buffer进行clear操作
      Arrays.asList(byteBuffers).stream().forEach(buffer -> buffer.clear());
      System.out.println("byteread=" + byteread + "bytewrite=" + byteWrite + "messagelength" + messageLength);
    }
  }
}
